// 派发与广播——自行实现 dispatch 和 broadcast 方法
// eg. 父组件向子组件（支持跨级）传递数据；
// eg. 子组件向父组件（支持跨级）传递数据。
// dispatch 和 broadcast，前者用于向上级派发事件，只要是它的父级（一级或多级以上），都可以在组件内通过 $on （或 events，2.x 已废弃）监听到，后者相反，是由上级向下级广播事件的。
function broadcast(componentName, eventName, params) {
	this.$children.forEach(child => {
		const name = child.$options.name
		if (name === componentName) {
			child.$emit.apply(child, [eventName].concat(params))
		} else {
			broadcast.apply(child, [componentName, eventName].concat([params]))
		}
	})
}
export default {
	methods: {
		dispatch(componentName, eventName, params) {
			let parent = this.$parent || this.$root
			let name = parent.$options.name
			while (parent && (!name || name !== componentName)) {
				parent = parent.$parent
				if (parent) {
					name = parent.$options.name
				}
			}
			if (parent) {
				parent.$emit.apply(parent, [eventName].concat(params))
			}
		},
		broadcast(componentName, eventName, params) {
			broadcast.call(this, componentName, eventName, params)
		}
	}
}

// // A.vue
// <template>
// 	<button @click="handleClick">触发事件</button>
// </template>
// <script>
//   import Emitter from '@/mixins/emitter.js';

//   export default {
//     name: 'componentA',
//     mixins: [ Emitter ],
//     methods: {
//       handleClick () {
//         this.broadcast('componentB', 'on-message', 'Hello Vue.js');
//       }
//     }
//   }
// </script>

// // B.vue
// export default {
//   name: 'componentB',
//   created () {
//     this.$on('on-message', this.showMessage);
//   },
//   methods: {
//     showMessage (text) {
//       window.alert(text);
//     }
//   }
// }
